import time

from django.db import models
from django.utils.crypto import random

from core.tl.client import get_TLClient
from core.tools.models import PublicPrivate
from core.tl.allinpay import mchNo, appId, AllinPay

class TLPayRecordManager(models.Manager):
    def create_record(self, orderNo, user_id, orderAmount, orderDatetime, orderCurrency=0, orderExpireDatetime=120,
                      url=None, channel_key="youpinhuiyuan"):
        self.create(
            orderNo=orderNo,
            merchantUserId=user_id,
            orderAmount=orderAmount,
            orderDatetime=orderDatetime,
            orderCurrency=orderCurrency,
            orderExpireDatetime=orderExpireDatetime,
            url=url,
            channel_key=channel_key
        )


class TLPayRecord(models.Model):
    """
    通联支付记录
    """
    url = models.CharField(verbose_name="前端跳转url", max_length=256, blank=True, null=True)
    merchantUserId = models.CharField(db_index=True, verbose_name="商户用户编号", max_length=64)
    orderNo = models.CharField(verbose_name="商户订单号, 对应SupplyOrder.out_trade_no", db_index=True, max_length=50)
    orderAmount = models.IntegerField(verbose_name="订单金额", help_text="以分为单位")
    payment = models.IntegerField(verbose_name="实付金额", help_text="实付金额要和订单金额一致才行", blank=True, null=True)
    orderDatetime = models.CharField(verbose_name="商户订单提交时间", max_length=14)
    orderExpireDatetime = models.IntegerField(verbose_name="订单过期时间")
    orderCurrency = models.IntegerField(verbose_name="币种类型", default=0, help_text="0代表人民币")
    payDatetime = models.CharField(verbose_name="支付完成时间", blank=True, null=True, max_length=64)
    is_pay = models.BooleanField(verbose_name="是否支付", default=False)
    paymentOrderId = models.CharField(verbose_name="通联订单号", max_length=50, help_text="只有支付完成才有", blank=True, null=True)
    channel_key = models.CharField(verbose_name="channel_key", max_length=32, default="youpinhuiyuan", db_index=True)
    objects = TLPayRecordManager()

    class Meta:
        verbose_name = "通联交易记录"
        verbose_name_plural = verbose_name

    def update_record(self, paymentOrderId, is_pay, payDatetime, payment):
        self.paymentOrderId = paymentOrderId
        self.is_pay = is_pay
        self.payDatetime = payDatetime
        self.payment = payment
        self.save()


class TLRefundRecordManager(models.Manager):
    def create_refund(self, **kwargs):
        data = dict()
        data["refundAmount"] = kwargs.get("refundAmount")
        data["orderDatetime"] = kwargs.get("orderDatetime")
        data["refundDatetime"] = kwargs.get("refundDatetime")
        data["refundResult"] = kwargs.get("refundResult")
        data["pay_record"] = kwargs.get("pay_record")
        data["mchtRefundOrderNo"] = kwargs.get("mchtRefundOrderNo")
        data["error_msg"] = kwargs.get("ERRORMSG")
        data["error_code"] = kwargs.get("ERRORCODE")
        instance = self.create(**data)
        return instance

    def tl_refund(self, refund_amount, order_no, tl_pay_record_obj, out_refund_no, channel_key=None):
        """
        通联退款
        :param refund_amount: 退款金额
        :param order_no: 支付时的订单号
        :param tl_pay_record_obj: 支付对象
        :param out_refund_no: 商户退款订单号
        :return:
        """
        order_datetime = tl_pay_record_obj.orderDatetime
        h5_client = get_TLClient(channel_key)
        response = h5_client.refund_api(refund_amount, order_no, order_datetime, out_refund_no)
        response["pay_record"] = tl_pay_record_obj
        if response.get("refundResult") == "20" or response.get("refundResult") == 20:
            # 成功
            self.create_refund(**response)
            return True, "OK"
        else:
            self.create_refund(**response)
            return False, response.get("ERRORMSG")

    def tl_refund_search(self, refund_amount, order_no, tl_pay_record_obj, channel_key=None):
        h5_client = get_TLClient(channel_key)
        response = h5_client.refund_search(refund_amount, order_no)
        key_list = list(response.keys())
        key = key_list[0]
        instance = self.filter(pay_record=tl_pay_record_obj).order_by("-id").first()
        if "TKSUCC0006" in key:
            instance.searchRefundResult = "TKSUCC0006"
        else:
            if "\r\n" in key:
                searchRefundResult = key.split("|")[6]
                instance.searchRefundResult = searchRefundResult
            else:
                instance.searchRefundResult = response
        instance.save()
        if instance.searchRefundResult == "TKSUCC0006":
            # 成功
            return True, "OK"
        else:
            return False, instance.searchRefundResult


class TLRefundRecord(models.Model):
    """
    通联退款记录
    """
    error_msg = models.CharField(max_length=128, blank=True, null=True, verbose_name="错误信息")
    error_code = models.CharField(max_length=8, blank=True, null=True, verbose_name="错误代码")
    pay_record = models.ForeignKey("TLPayRecord", verbose_name="对应的支付记录")
    refundAmount = models.IntegerField(verbose_name="退款金额", help_text="以分为单位", blank=True, null=True)
    orderDatetime = models.CharField(max_length=14, verbose_name="提交退款时间", blank=True, null=True)
    refundDatetime = models.CharField(verbose_name="退款受理时间", max_length=14, blank=True, null=True)
    refundResult = models.CharField(max_length=10, verbose_name="退款状态", help_text="20为成功其他为失败")
    searchRefundResult = models.CharField(max_length=128, verbose_name="查询退款状态", help_text="TKSUCC0006为成功其他为失败",
                                          blank=True, null=True)
    mchtRefundOrderNo = models.CharField(max_length=28, verbose_name="商户退款订单号", blank=True, null=True)
    out_refund_no = models.CharField(max_length=28, verbose_name="商户退款订单号（对应订单退款表）", blank=True, null=True)
    objects = TLRefundRecordManager()

    class Meta:
        verbose_name = "通联退款记录"
        verbose_name_plural = verbose_name


class TLTransferRecord(models.Model):
    resClsChoice = (("00", "成功"), ("01", "失败"))
    SHDD = models.CharField(max_length=64, verbose_name="商户订单号")
    resCls = models.CharField(max_length=4, verbose_name="resCls", choices=resClsChoice)
    cash = models.IntegerField(verbose_name="提现金额")
    JYMS = models.CharField(max_length=64, verbose_name="交易结果描述")
    TLDD = models.CharField(max_length=64, verbose_name="通联订单号", blank=True, null=True, help_text="成功才有")
    timestamp = models.CharField(max_length=24, verbose_name="订单时间")

    class Meta:
        verbose_name = "提现记录"
        verbose_name_plural = verbose_name


class AllinPayOrderManager(models.Manager):
    def create_order(self, kwargs):
        data = dict()
        mchOrderNo = kwargs.get("mchOrderNo")
        state = kwargs.get("state")
        queryset = self.filter(mchOrderNo=mchOrderNo, state=state)
        if queryset.exists():
            return queryset.first()
        else:
            data["appId"] = appId
            data["mchNo"] = mchNo
            data["reqTime"] = kwargs.get("reqTime")
            data["mchOrderNo"] = mchOrderNo
            data["amount"] = kwargs.get("amount")
            data["state"] = kwargs.get("state")
            data["body"] = kwargs.get("body")
            data["payOrderId"] = kwargs.get("payOrderId")
            data["channelExtra"] = kwargs.get("channelExtra")
            data["bank_code"] = kwargs.get("channelUser")[:5]
            data["channelUser"] = kwargs.get("channelUser")
            data["channelAcctType"] = kwargs.get("channelAcctType")
            instance = self.create(**data)
            return instance


# 通联微信小程序支付
class AllinPayOrder(models.Model):
    state = models.SmallIntegerField(default=0, verbose_name="订单状态")
    mchNo = models.CharField(max_length=30, verbose_name="商户号")
    appId = models.CharField(max_length=25, verbose_name="应用ID")
    reqTime = models.CharField(max_length=13, verbose_name="请求接口时间")
    version = models.CharField(max_length=3, verbose_name="请求接口时间", default="1.0")
    signType = models.CharField(max_length=6, verbose_name="请求接口时间", default="MD5")
    mchOrderNo = models.CharField(max_length=30, verbose_name="商户订单号")
    payOrderId = models.CharField(max_length=30, verbose_name="支付订单号，与mchOrderNo二者传一即可")
    wayCode = models.CharField(max_length=30, verbose_name="WX_LITE")
    amount = models.CharField(max_length=8, verbose_name="金额分")
    currency = models.CharField(max_length=8, verbose_name="金额分", default="cny")
    body = models.CharField(max_length=256, verbose_name="商品描述")
    notifyUrl = models.CharField(max_length=256, verbose_name="支付结果通知", blank=True, null=True)
    returnUrl = models.CharField(max_length=256, verbose_name="支付结果同步跳转通知URL", blank=True, null=True)
    channelExtra = models.CharField(max_length=512, verbose_name="渠道参数", blank=True, null=True)
    bank_code = models.CharField(max_length=6, verbose_name="银行code", blank=True, null=True)
    channelUser = models.CharField(max_length=20, verbose_name="用户卡信息", blank=True, null=True)
    channelAcctType = models.CharField(max_length=4, verbose_name="	账户类型", blank=True, null=True)
    objects = AllinPayOrderManager() #


    class Meta:
        verbose_name = "通联微信小程序支付"
        verbose_name_plural = verbose_name

class AllinPayUnifiedOrderManager(models.Manager):

    def create_refund_order(self, mchOrderNo, amount, payOrderId=""):
        reqTime = str(int(time.time() * 1000))
        mchRefundNo = reqTime + str(random.randint(100000,999999))
        instance = self.create(
            mchRefundNo=mchRefundNo,
            mchOrderNo=mchOrderNo,
            payOrderId=payOrderId,
            amount=amount,
            reqTime=reqTime,
        )
        alliPay = AllinPay()
        content = alliPay.refundOrder(reqTime, mchRefundNo, mchOrderNo, amount)
        # content = {"code": 0,"data": {"channelOrderNo": "532506171543009670218", "mchRefundNo": "1750158156250953521", "payAmount": 699,
        #           "refundAmount": 699, "refundOrderId": "R1934929763136966657", "state": 1}, "msg": "SUCCESS",
        #  "sign": "AF33189C113DC4FD23770BF7EC2AB479"}

        data = content.get("data")
        instance.msg = content.get("msg")
        instance.state = data.get("state")
        instance.refundOrderId = data.get("refundOrderId")
        instance.save()
        # instance.payAmount = data.get("payAmount")
        return content, mchRefundNo


class AllinPayUnifiedOrder(models.Model):
    orderState = ((0,"订单生成"),(1,"退款中"),(2,"退款成功"),(3,"退款失败"),(4,"退款关闭"),)
    mchRefundNo = models.CharField(max_length=30, verbose_name="商户退款订单号")
    mchOrderNo = models.CharField(max_length=30, verbose_name="商户订单号")
    payOrderId = models.CharField(max_length=30, verbose_name="支付订单号，与mchOrderNo二者传一即可")
    amount = models.CharField(max_length=8, verbose_name="金额分")
    reqTime = models.CharField(max_length=13, verbose_name="请求接口时间")
    # 返回结果
    refundOrderId = models.CharField(max_length=30, verbose_name="退款订单号", blank=True, null=True)
    # ****后期留的字段 实际是退款金额金额*****
    payAmount = models.IntegerField(verbose_name="退款金额分", blank=True, null=True)  # 后期留的字段 实际是退款金额金额
    state = models.IntegerField(verbose_name="退款状态", blank=True, null=True, choices=orderState)
    successTime = models.CharField(max_length=13, verbose_name="退款成功时间", blank=True, null=True)
    msg = models.CharField(max_length=128, verbose_name="信息", blank=True, null=True)
    objects = AllinPayUnifiedOrderManager()

    class Meta:
        verbose_name = "通联微信小程序支付退款"
        verbose_name_plural = verbose_name


    def update_state(self, state, successTime, refundAmount, refundOrderId):
        self.state = state
        self.successTime = successTime
        self.refundOrderId = refundOrderId
        self.payAmount = refundAmount
        self.save()
